import re

import requests
from account.ydt_account_service import YdtAccountService
from model.park_spider import ParkSpider
from model.park_platform import ParkPlatform
from model.car_number import CarNumber
from model.result import Result
from model.error import ParkSpiderError, ParkSpiderErrorCode, TokenExpireError

import dateutil.parser as dateutil

from urllib import parse
import common.http as http
import spider_config
import json
from datetime import datetime
import time
from common.logger import logger
from database.park_location_record_table import ParkLocationRecordTable


class YdtParkSpider(ParkSpider):
    def platform(self) -> ParkPlatform:
        return ParkPlatform(spider_config.ydt_park_id)

    def is_in_park(self, carNumber: CarNumber):
        url = "https://wxydt.yidianting.xin/user/visitPay/isHaveSameCarIn.do"

        account = YdtAccountService.instance().take()

        if not account:
            raise ParkSpiderError(ParkSpiderErrorCode.YdtAccountEmpty)

        params = {
            "auth_code": account["auth_code"],
            "carNo": str(carNumber),
        }

        rsp = http.get(
            url,
            params=params,
            proxies=self.getProxy(),
            timeout=self.getTimeout(),
        )

        if not rsp.text:
            raise TokenExpireError(account["auth_code"])

        rspJson = rsp.json()

        logger.debug(f"一点停查询状态 {carNumber} 结果:{rspJson}")

        if rspJson["resultCode"] == 0 and rspJson["status"] == 1:
            return False if not rspJson["data"] else True

        logger.error(f"一点停查询状态失败:{rspJson}")

        return False

    def query(self, carNumber: CarNumber) -> Result:
        result = Result()
        result.platform = self.platform()
        result.car_number = carNumber

        if not self.is_in_park(carNumber):
            return result

        account = YdtAccountService.instance().take()

        if not account:
            raise ParkSpiderError(ParkSpiderErrorCode.YdtAccountEmpty)

        url = "https://wxydt.yidianting.xin/user/charge/charge/parkingCharge.do"

        params = {
            "auth_code": account["auth_code"],
            "token": account["token"],
            "carNo": str(carNumber),
            "test": "1",
            "vistor": "1",
            "notoken": "1",
            "isFromChannel": "",
            "uiurl": "",
            "parkId": "",
        }

        headers = {
            "Host": "wxydt.yidianting.xin",
            "Accept": "application/json, text/plain, */*",
            "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.33(0x18002126) NetType/WIFI Language/en",
        }

        rsp = http.get(
            url,
            headers=headers,
            params=params,
            proxies=self.getProxy(),
            timeout=self.getTimeout(),
        )

        if not rsp.text:
            raise TokenExpireError(account["auth_code"])

        rspJson = rsp.json()

        # logger.debug(f"一点停查询 {carNumber} 结果:{rspJson}")

        if rspJson["resultCode"] == 100 and rspJson["status"] == 2:
            logger.error(f"一点停查询 {carNumber} 失败:{rspJson}")
            time.sleep(10)
            return self.query(carNumber)

        if rspJson["resultCode"] != 0 or rspJson["status"] != 1 or not rspJson["data"]:
            logger.error(f"一点停查询 {carNumber} 失败:{rspJson}")
            return result

        if rspJson["data"]["isLeave"]:
            logger.info(f"一点停查询 {carNumber} 不在场:{result}")
            return result

        result.success = True
        result.enter_time = dateutil.parse(rspJson["data"]["inTime"])
        result.platform = self.platform()
        parkId = rspJson["data"]["parkId"]

        with ParkLocationRecordTable() as db:
            result.park_name = db.query(parkId)
            if not result.park_name:
                logger.error(f"一点停车场匹配失败{carNumber}:{parkId}")

        logger.debug(f"一点停查询成功:{result}")

        return result
